/**
 * @brief    平面六节点三角形截面属性计算单元测试
 * 
 * @version  0.1
 * @author   Liu Xing
 * @date     2025.10.17
 * @copyright Copyright (c) 2025
 */

#include "DataStructure/Common/Constant.h"
#include "gtest/gtest.h"
#include "../Tri6Element.h"

using SG::DataStructure::Common::TOLERANCE;
using SG::Algebra::Matrixd;
using SG::FEMSolver::BeamElement::Tri6Element;
using SG::FEMSolver::BeamElement::EleGeomProp;

static Matrixd triCoord(6, 2, {
                            0.0, 0.0,
                            2.0, 0.0,
                            0.0, 2.0,
                            1.0, 0.0,
                            1.0, 1.0,
                            0.0, 1.0,});

// 测试面积计算
TEST(Tri6ElementTest, CalculateGeomPropTest)
{
    Tri6Element ele;
    ele.Initialize();
    ele.CalculateGeomProp(triCoord);
    EleGeomProp eleGeoProp = ele.GetGeomProp();
    EXPECT_NEAR(eleGeoProp.Area, 2.0, TOLERANCE); 
    EXPECT_NEAR(eleGeoProp.Qy, 4.0/3.0, TOLERANCE);
    EXPECT_NEAR(eleGeoProp.Qz, 4.0/3.0, TOLERANCE);
    EXPECT_NEAR(eleGeoProp.Iy, 4.0/3.0, TOLERANCE);
    EXPECT_NEAR(eleGeoProp.Iz, 4.0/3.0, TOLERANCE);
    EXPECT_NEAR(eleGeoProp.Iyz,2.0/3.0, TOLERANCE);
}

// 测试计算单元积分项ComputeShearCoeffIntegralTerm()
TEST(Tri6ElementTest, ComputeShearCoeffIntegralTermTest)
{
    Tri6Element ele;
    ele.Initialize();

    // 构造线性分布 psi, phi
    Matrixd psi(6, 1), phi(6, 1);
    for (size_t i = 0; i < 6; ++i)
    {
        psi(i, 0) = static_cast<Real>(i);
        phi(i, 0) = static_cast<Real>(i) * 0.5;
    }

    const auto result = ele.ComputeShearCoeff(triCoord, {1.0, 1.0, 0.0}, 0.0, psi, phi);
    ASSERT_TRUE (result == Matrixd(3, 1, {33.166666666666693, 8.2916666666666732, 16.583333333333346}));
}

// 测试计算单元矩阵ComputeEleMatrix()
TEST(Tri6ElementTest, ComputeEleMatrixTest)
{
    Tri6Element ele;
    ele.Initialize();

    Matrixd Ke;
    std::vector<Matrixd> F;
    ele.ComputeEleMatrix(triCoord, {1.0, 1.0, 0.0}, 0.0, Ke, F);
    
    // Check
    ASSERT_NEAR (Ke(0, 0), 1.0000000000000007, TOLERANCE);
    ASSERT_NEAR (Ke(1, 1), 0.50000000000000067, TOLERANCE);
    ASSERT_NEAR (Ke(5, 5), 2.6666666666666683, TOLERANCE);
    ASSERT_NEAR (F[0](3,0), 4.0/3.0, TOLERANCE);
    ASSERT_NEAR (F[1](3,0), 1.0666666666666642, TOLERANCE);
    ASSERT_NEAR (F[2](3,0), 0.53333333333333166, TOLERANCE);
}

// 测试计算单元扇形积
TEST (Tri6ElementTest, ComputeSectorProductGaussIntegral)
{
    Matrixd eleNodeOmega (6, 1, {2.0, 4.0, 6.0, 8.0, 16.0, 24.0});

    // Test data
    Tri6Element tri6;
    tri6.Initialize ();
    auto IyzwTest = tri6.ComputeSectorProduct (triCoord, eleNodeOmega);

    // Target data
    Matrixd IyzwTarget (1, 2, {19.2, 23.866666666666632});

    // Check
    ASSERT_TRUE (IyzwTarget == IyzwTest);
}